package com.inspur.security.cbb3.kms.exception;

import com.inspur.security.cbb3.kms.enums.SystemCode;
import com.inspur.security.cbb3.kms.utils.ResultUtil;
import javassist.NotFoundException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.web.firewall.RequestRejectedException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ValidationException;
import java.util.List;

/**
 * 异常处理类
 * controller层异常无法捕获处理，需要自己处理
 *
 * @author lijunchang
 */
@RestControllerAdvice
@Slf4j
public class DefaultExceptionHandler {

    /**
     * 请求方式不正确
     */
    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    public ResponseEntity handleHttpRequestMethodNotSupportedExceptionHandle(HttpRequestMethodNotSupportedException e) {
        log.error(e.getLocalizedMessage());
        return ResultUtil.noDataReturn(SystemCode.ERR_METHOD_NOT_ALLOWED, HttpStatus.METHOD_NOT_ALLOWED);
    }

    /**
     * 传入参数不合规
     */
    @ExceptionHandler(value = BindException.class)
    public ResponseEntity handleBindExceptionHandle(BindException e) {
        log.error(e.getLocalizedMessage());
        BindingResult bindingResult=e.getBindingResult();
        List<FieldError> errors=bindingResult.getFieldErrors();
        StringBuffer sb=new StringBuffer();
        for(FieldError error:errors){
            sb.append("参数【"+error.getField()+"】");
            sb.append(error.getDefaultMessage()+"\n\r");
        }
        return ResultUtil.noDataReturn(SystemCode.ERR_BAD_REQUEST.getCode(), "传入参数不合规，错误原因：\n\r"+sb.toString(),HttpStatus.BAD_REQUEST);
    }

    /**
     * 参数校验失败
     */
    @ExceptionHandler(value = ValidationException.class)
    public ResponseEntity handleValidationExceptionHandle(ValidationException e) {
        log.error(e.getLocalizedMessage());
        return ResultUtil.noDataReturn(SystemCode.ERR_BAD_REQUEST.getCode(), "传入参数不合规，错误原因：\n\r"+e.getLocalizedMessage(),HttpStatus.BAD_REQUEST);
    }

    /**
     * 资源未找到
     */
    @ExceptionHandler(value = NotFoundException.class)
    public ResponseEntity handleNotFoundExceptionHandle(NotFoundException e) {
        log.error(e.getLocalizedMessage());
        return ResultUtil.noDataReturn(SystemCode.ERR_NOTFOUND, HttpStatus.NOT_FOUND);
    }



    /**
     * 内部业务错误
     */
    @ExceptionHandler(value = RequestRejectedException.class)
    public ResponseEntity handleRequestRejectedExceptionHandle(RequestRejectedException e) {
        log.error(e.getLocalizedMessage());
        return ResultUtil.noDataReturn(SystemCode.ERR_INNER_ERROR, HttpStatus.INTERNAL_SERVER_ERROR);
    }


    /**
     * 用户信息无效异常
     */
    @ExceptionHandler(value = UserInfoInVaildException.class)
    public ResponseEntity handleUserInfoInvaildExceptionHandle(UserInfoInVaildException e) {
        log.error(e.getLocalizedMessage());
        return ResultUtil.noDataReturn(SystemCode.ERR_USER_INFO_INVALID, HttpStatus.FORBIDDEN);
    }

    /**
     * 处理登录接口用户失效
     */
    @ExceptionHandler(InternalAuthenticationServiceException.class)
    public ResponseEntity handleInternalAuthenticationServiceExceptionHandle(InternalAuthenticationServiceException e) {
        log.error(e.getLocalizedMessage());
        Class ec = e.getCause().getClass();
        if (LockedException.class.equals(ec)) {
            return ResultUtil.noDataReturn(SystemCode.ERR_LOGIN_IP, HttpStatus.FORBIDDEN);
        } else if (BadCredentialsException.class.equals(ec)) {
            return ResultUtil.noDataReturn(SystemCode.ERR_LOGIN_PARAMETER, HttpStatus.BAD_REQUEST);
        }
        return ResultUtil.noDataReturn(SystemCode.ERR_FORBIDDEN.getCode(), e.getMessage(), HttpStatus.FORBIDDEN);
    }

    /**
     * 请求参数不正确，不规范，使用ValidationException
     * 请求参数不正确，丢失,缺少等,使用MissingServletRequestParameterException
     * 等参数错误，均使用全局错误
     * 全局错误
     */
    @ExceptionHandler(value = Exception.class)
    public ResponseEntity handleExceptionHandle(Exception e) {
        log.error(e.getLocalizedMessage());
        return ResultUtil.noDataReturn(SystemCode.ERR_BAD_REQUEST, HttpStatus.BAD_REQUEST);
    }

}
